package sk.mka.phd.googleagent.query;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.MessageFormat;
import org.apache.log4j.Logger;

/**
 *
 * @author bracek
 * @date Aug 3, 2010
 */
public class YahooQuery  extends AbstractGoogleQuery implements IGoogleQuery {

    private static final Logger log = Logger.getLogger(YahooQuery.class);
    // Need to have an application ID to call the Yahoo! services.
    private static final String APPLICATION_ID = "insert app ID";
// URL format for the request. The simplest request includes the
// application ID and the query. See the service documentation for
// a list of additional parameters.
    private static final String WEB_SEARCH_URL_FORMAT =
            "http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid={0}&query={1}";

    @Override
    public String makeQuery(String query) {
        printCountRequest();
//        System.out.println("query = " + query);

        String totalResultsAvailable = null;
        try {
            //
            // Construct the query from the command line arguments.
            //  query = prepareQuery(query);
            // Construct the URL. Inject the URL encoded application ID and
            // the search query.
            log.info(query);
            URL url = new URL(MessageFormat.format(WEB_SEARCH_URL_FORMAT, new Object[]{URLEncoder.encode(APPLICATION_ID, "utf-8"), URLEncoder.encode(query, "utf-8")}));
//           System.out.println("Request URL = " + url.toString());
            // Create an XPath engine.
            XPath xpath = XPathFactory.newInstance().newXPath();
            // Execute the query.
            Document responseDocument = null;
            try {
                // We need a Document to use XPath.
                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                responseDocument = builder.parse(url.openStream());
            } catch (ParserConfigurationException ex) {
//                Logger.getLogger(YahooQuery.class.getName()).log(Level.SEVERE, null, ex);
                log.debug(ex);
            } catch (IOException e) {
                // Error calling the service.
                System.err.println("Error calling the service: " + e.toString());
                e.printStackTrace(System.err);
                System.exit(1);
            } catch (SAXException e) {
                // Error parsing the XML.
                System.err.println("Error parsing the XML: " + e.toString());
                e.printStackTrace(System.err);
                System.exit(1);
            }
            totalResultsAvailable = (String) xpath.evaluate(
                    "/ResultSet/@totalResultsAvailable",
                    responseDocument,
                    XPathConstants.STRING);
//            System.out.println("Total results available for '" + query + "' is " + totalResultsAvailable);

// Query the XML for the URLs.
//        NodeList urls = (NodeList) xpath.evaluate("/ResultSet/Result/Url",
//                responseDocument, XPathConstants.NODESET);
//        for (int i = 0; i < urls.getLength(); i++) {
//                org.w3c.dom.Node urlNode = urls.item(i);
//            System.out.println("URL " + (i + 1) + ": "
//                    + urlNode.getTextContent());
//        }
        } catch (XPathExpressionException ex) {
//            Logger.getLogger(YahooQuery.class.getName()).log(Level.SEVERE, null, ex);
            log.debug(ex);
        } catch (MalformedURLException ex) {
//            Logger.getLogger(YahooQuery.class.getName()).log(Level.SEVERE, null, ex);
            log.debug(ex);
        } catch (UnsupportedEncodingException ex) {
//            Logger.getLogger(YahooQuery.class.getName()).log(Level.SEVERE, null, ex);
            log.debug(ex);
        }
        return totalResultsAvailable;

    }

    /**
     * Simple method that stitches together an array of strings into
     * a single string. Used to take multiple command line arguments
     * and turn it into a single query string.
     *
     *@param args The individual strings to stitch together.
     *@return A new string containing each of the strings passed in, all
     *seperated by spaces.
     */
    private static String prepareQuery(String[] args) {
        String query;
        StringBuffer queryBuffer = new StringBuffer();
        for (int i = 0; i < args.length; i++) {
            queryBuffer.append(args[i]);
            if ((i + 1) < args.length) {
                queryBuffer.append(" ");

            }
        }
        query = queryBuffer.toString();
        return query;

    }
}
